package dos

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"sync"
	"time"
)

// DOSAttackResult DOS攻击结果
type DOSAttackResult struct {
	TargetHost         string            `json:"target_host"`
	TargetPort         string            `json:"target_port"`
	TargetURL          string            `json:"target_url,omitempty"`
	AttackType         string            `json:"attack_type"`
	StartTime          time.Time         `json:"start_time"`
	EndTime            time.Time         `json:"end_time"`
	Duration           float64           `json:"duration_seconds"`
	SuccessCount       int64             `json:"success_count"`
	FailCount          int64             `json:"fail_count"`
	StatusCodes        map[int]int       `json:"status_codes,omitempty"`
	PreAttackTime      float64           `json:"pre_attack_time_seconds,omitempty"`
	PostAttackTime     float64           `json:"post_attack_time_seconds,omitempty"`
	PerformanceImpact  float64           `json:"performance_impact_score,omitempty"`
	AvailabilityImpact float64           `json:"availability_impact_score,omitempty"`
	EffectivenessLevel string            `json:"effectiveness_level,omitempty"`
	Parameters         map[string]string `json:"parameters,omitempty"`
}

// DOSAttackDB DOS攻击数据库，用于存储和检索攻击结果
type DOSAttackDB struct {
	dataDir string
	results []DOSAttackResult
	mutex   sync.RWMutex
}

// NewDOSAttackDB 创建新的DOS攻击数据库
func NewDOSAttackDB(dataDir string) (*DOSAttackDB, error) {
	if dataDir == "" {
		dataDir = "./dosdb"
	}

	// 确保数据目录存在
	if err := os.MkdirAll(dataDir, 0755); err != nil {
		return nil, fmt.Errorf("创建数据目录失败: %v", err)
	}

	db := &DOSAttackDB{
		dataDir: dataDir,
		results: make([]DOSAttackResult, 0),
	}

	// 加载已有的攻击结果
	if err := db.loadResults(); err != nil {
		return db, err // 返回部分初始化的DB，加载错误不致命
	}

	return db, nil
}

// SaveResult 保存攻击结果
func (db *DOSAttackDB) SaveResult(result DOSAttackResult) error {
	db.mutex.Lock()
	defer db.mutex.Unlock()

	// 添加到内存中
	db.results = append(db.results, result)

	// 生成文件名
	filename := fmt.Sprintf("attack_%s_%d.json",
		result.AttackType,
		result.StartTime.Unix())

	// 完整文件路径
	filepath := filepath.Join(db.dataDir, filename)

	// 序列化为JSON
	data, err := json.MarshalIndent(result, "", "  ")
	if err != nil {
		return fmt.Errorf("序列化JSON失败: %v", err)
	}

	// 写入文件
	if err := os.WriteFile(filepath, data, 0644); err != nil {
		return fmt.Errorf("写入文件失败: %v", err)
	}

	return nil
}

// GetResults 获取所有攻击结果
func (db *DOSAttackDB) GetResults() []DOSAttackResult {
	db.mutex.RLock()
	defer db.mutex.RUnlock()

	// 创建副本返回
	results := make([]DOSAttackResult, len(db.results))
	copy(results, db.results)

	return results
}

// GetResultsByTarget 根据目标获取攻击结果
func (db *DOSAttackDB) GetResultsByTarget(host string) []DOSAttackResult {
	db.mutex.RLock()
	defer db.mutex.RUnlock()

	var filtered []DOSAttackResult
	for _, result := range db.results {
		if result.TargetHost == host {
			filtered = append(filtered, result)
		}
	}

	return filtered
}

// GetResultsByType 根据攻击类型获取攻击结果
func (db *DOSAttackDB) GetResultsByType(attackType string) []DOSAttackResult {
	db.mutex.RLock()
	defer db.mutex.RUnlock()

	var filtered []DOSAttackResult
	for _, result := range db.results {
		if result.AttackType == attackType {
			filtered = append(filtered, result)
		}
	}

	return filtered
}

// GetMostEffectiveAttack 获取对指定目标最有效的攻击类型
func (db *DOSAttackDB) GetMostEffectiveAttack(host string) (string, float64) {
	results := db.GetResultsByTarget(host)

	var bestType string
	var bestScore float64

	for _, result := range results {
		score := (result.PerformanceImpact + result.AvailabilityImpact) / 2
		if score > bestScore {
			bestScore = score
			bestType = result.AttackType
		}
	}

	return bestType, bestScore
}

// loadResults 从数据目录加载攻击结果
func (db *DOSAttackDB) loadResults() error {
	// 读取目录中的所有JSON文件
	pattern := filepath.Join(db.dataDir, "attack_*.json")
	files, err := filepath.Glob(pattern)
	if err != nil {
		return fmt.Errorf("查找结果文件失败: %v", err)
	}

	for _, file := range files {
		// 读取文件内容
		data, err := os.ReadFile(file)
		if err != nil {
			continue // 跳过错误文件
		}

		// 解析JSON
		var result DOSAttackResult
		if err := json.Unmarshal(data, &result); err != nil {
			continue // 跳过格式错误的文件
		}

		// 添加到内存中
		db.results = append(db.results, result)
	}

	return nil
}

// DOSAttackOptimizer DOS攻击优化器
type DOSAttackOptimizer struct {
	db *DOSAttackDB
}

// NewDOSAttackOptimizer 创建新的DOS攻击优化器
func NewDOSAttackOptimizer(db *DOSAttackDB) *DOSAttackOptimizer {
	return &DOSAttackOptimizer{
		db: db,
	}
}

// OptimizeAttackParams 优化攻击参数
func (o *DOSAttackOptimizer) OptimizeAttackParams(targetHost string, attackType string) map[string]string {
	// 省略实现代码，实际应保留完整内容
	return nil
}

// SuggestAttackType 根据目标信息推荐攻击类型
func (o *DOSAttackOptimizer) SuggestAttackType(targetInfo *TargetInfo) string {
	// 省略实现代码，实际应保留完整内容
	return ""
}
